

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class TextFileIndexer {

	private static final String FIELD_PATH = "path";
	StandardAnalyzer analyzer;
	private String indexDir;
	FSDirectory dir;
	private IndexWriter writer;
	ArrayList<File> queue;
	
	public TextFileIndexer(String indexDir, StandardAnalyzer analyzer) throws IOException{
		
		this.analyzer = analyzer;
		queue = new ArrayList<File>();
		
		this.indexDir = indexDir;
		dir = FSDirectory.open(new File(indexDir));
		
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_46, analyzer);
	    writer = new IndexWriter(dir, config);
	   
	}
	
	public void deleteAllDocuments(){
		try {
			writer.deleteAll();
			System.out.println("Number of Documents remaining: " +getCurrentNumDocs());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void clearIndexDir(){
		File file = new File(indexDir);
		for(File f : file.listFiles()){
			deleteFile(f);
		}
	}
	
	
	 /**
	   * Close the index.
	   * @throws java.io.IOException when exception closing
	   */
	  public void closeIndex() throws IOException {
	    writer.close();
	  }


	  /**
	   * Indexes a file or directory
	   * @param fileName the name of a text file or a folder we wish to add to the index
	   * @throws java.io.IOException when exception
	   */
	public String indexFileOrDirectory(String fileName) throws IOException {
		//===================================================
	    //gets the list of files in a folder (if user has submitted
	    //the name of a folder) or gets a single file name (is user
	    //has submitted only the file name) 
	    //===================================================
		
		
		String result = "";
	    addFiles(new File(fileName));
	    
	    int originalNumDocs = writer.numDocs();
	    for (File f : queue) {
	      FileReader fr = null;
	      try {
	        Document doc = new Document();

	        //===================================================
	        // add contents of file
	        //===================================================
	        fr = new FileReader(f);
	        doc.add(new TextField("contents", fr));
	        doc.add(new StringField("path", f.getPath(), Field.Store.YES));
	        doc.add(new StringField("filename", f.getName(), Field.Store.YES));

	        writer.addDocument(doc);
	        result += ("Added: " + f + "\n");
	      } catch (Exception e) {
	        result += ("Could not add: " + f + "\n");
	      } finally {
	        fr.close();
	      }
	    }
	    
	    int newNumDocs = writer.numDocs();
	    result += ("\n");
	    result += ("************************" + "\n");
	    result += ((newNumDocs - originalNumDocs) + " documents added." + "\n");
	    result += ("************************" + "\n");

	    queue.clear();
	    return result;
	}




	private void addFiles(File file) {
		if (!file.exists()) {
			System.out.println(file + " does not exist.");
		}
		if (file.isDirectory()) {
			for (File f : file.listFiles()) {
				addFiles(f);
			}
		} else {
			String filename = file.getName().toLowerCase();
			// ===================================================
			// Only index text files
			// ===================================================
			if (filename.endsWith(".htm") || filename.endsWith(".html")
					|| filename.endsWith(".xml") || filename.endsWith(".txt")) {
				queue.add(file);
			} else {
				System.out.println("Skipped " + filename);
			}
		}
	}
	
	
	private void deleteFile(File file){
		if (!file.exists()) {
			System.out.println(file + " does not exist.");
		}
		if(file.isDirectory()){
			for(File f : file.listFiles()){
				deleteFile(f);
			}
		} else {
			file.delete();
		}
		
	}

	public int getCurrentNumDocs() {
		return writer.numDocs();
	}

	
	public void removeDocument(String absolutPath) {
		Term term = new Term(FIELD_PATH, absolutPath);
		try {
			writer.deleteDocuments(term);
			writer.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
}
